using System.Collections.Generic;
using MyFramework.Singleton;
using UnityEngine.Events;

namespace MyFramework.Event
{
    public interface IEventInfo 
    { 
        //空接口，避免拆箱装箱带来的性能消耗
    }

    public class EventInfo<T> : IEventInfo
    {
        public UnityAction<T> Action;

        public EventInfo(UnityAction<T> action)
        {
            Action += action;
        }
            
    }

    public class EventInfo : IEventInfo
    {
        public UnityAction Action;

        public EventInfo(UnityAction action)
        {
            Action += action;
        }

    }

    /// <summary>
    /// 事件中心模块
    /// </summary>
    public class EventCenterManager : Singleton<EventCenterManager>
    {
        /// <summary>
        /// key - 事件的名字
        /// value - 监听这个事件的委托函数们
        /// 带参数的委托
        /// </summary>
        private readonly Dictionary<string, IEventInfo> _eventCenter = new Dictionary<string, IEventInfo>();

        /// <summary>
        /// 添加事件监听（有参数）
        /// </summary>
        /// <param name="name">事件的名字</param>
        /// <param name="action">处理事件的委托函数</param>
        public void AddEventListener<T>(string name, UnityAction<T> action)
        {
            //有没有对应的事件监听
            if (_eventCenter.TryGetValue(name, out var eventInfo))
            {
                ((EventInfo<T>)eventInfo).Action += action;
            }
            else
            {
                _eventCenter.Add(name, new EventInfo<T>(action));
            }
        }

        /// <summary>
        /// 添加事件监听（无参数）
        /// </summary>
        /// <param name="name">事件的名字</param>
        /// <param name="action">处理事件的委托函数</param>
        public void AddEventListener(string name, UnityAction action)
        {
            //有没有对应的事件监听
            if (_eventCenter.TryGetValue(name, out var eventInfo))
            {
                ((EventInfo)eventInfo).Action += action;
            }
            else
            {
                _eventCenter.Add(name, new EventInfo(action));
            }
        }

        /// <summary>
        /// 移除事件监听（有参数）
        /// </summary>
        /// <param name="name">事件的名字</param>
        /// <param name="action">之前添加的处理事件的委托函数</param>
        public void RemoveEventListener<T>(string name, UnityAction<T> action)
        {
            //有没有对应的事件监听
            if (_eventCenter.TryGetValue(name, out var eventInfo))
            {
                ((EventInfo<T>)eventInfo).Action -= action;
            }
        }

        /// <summary>
        /// 移除事件监听（无参数）
        /// </summary>
        /// <param name="name">事件的名字</param>
        /// <param name="action">之前添加的处理事件的委托函数</param>
        public void RemoveEventListener(string name, UnityAction action)
        {
            //有没有对应的事件监听
            if (_eventCenter.TryGetValue(name, out var value))
            {
                ((EventInfo)value).Action -= action;
            }
        }

        /// <summary>
        /// 事件触发（有参数）
        /// </summary>
        /// <param name="name">触发事件的名字</param>
        /// <param name="param">事件参数</param>
        public void EventTrigger<T>(string name, T param)
        {
            //只处理有事件监听的情况
            if (_eventCenter.TryGetValue(name, out var eventInfo))
            {
                ((EventInfo<T>)eventInfo).Action?.Invoke(param);
            }
        }

        /// <summary>
        /// 事件触发（无参数）
        /// </summary>
        /// <param name="name">触发事件的名字</param>
        public void EventTrigger(string name)
        {
            //只处理有事件监听的情况
            if (_eventCenter.TryGetValue(name, out var eventInfo))
            {
                ((EventInfo)eventInfo).Action?.Invoke();
            }
        }

        /// <summary>
        /// 清空事件中心
        /// 主要用在场景切换时，防止内存泄漏
        /// </summary>
        public void Clear()
        {
            _eventCenter.Clear();
        }
    }
}
